//
// Created by A on 2018/9/18.
//

#include <stdlib.h>
#include <assert.h>
#include <MemCheckerC.h>
#include "List.h"


Node *createNewNode(void *data);

Node *getNodeAt(List *list, int index);

List *list_new() {
    List *list = Malloc(sizeof(List));
    list->head = NULL;
    list->tail = NULL;
    list->len = 0;

    return list;
}

int list_len(List *list) {
    if (list == NULL) {
        return 0;
    } else {
        return list->len;
    }
}

void list_append(List *list, void *data) {
    if (list == NULL) {
        return;
    }

    if (data == NULL) {
        return;
    }

    Node *node = createNewNode(data);

    if (list->head == NULL) {
        //说明列表中没有数据
        list->head = node;
    } else {
        //head 不为null，tail也一定不为null。
        list->tail->next = node;
    }

    list->tail = node;
    list->len += 1;

}

Node *createNewNode(void *data) {
    Node *node = Malloc(sizeof(Node));
    node->data = data;
    node->next = NULL;
    return node;
}


/**
 * 比如： 0（0） ， 1（1）， 2（2）.  index = 0（1）。name结果是
 *  0（1） ， 0（0） ， 1（1）， 2（2）
 *  比如： 0（0） ， 1（1）， 2（2）.  index = 4（1）。name结果是
 *   0（0） ， 1（1）， 2（2），0（1）
 *
 *  比如： 0（0） ， 1（1）， 2（2）.  index = 2（1）。name结果是
 *   0（0） ， 1（1），2(1),  2（2）
 * @param list
 *
 * @param data
 * @param index
 */
void list_insertAt(List *list, void *data, int index) {
    if (list == NULL) {
        return;
    }

    if (data == NULL) {
        return;
    }

    int len = list->len;

    if (index >= len) {
        //超出列表长度范围，按添加到最后处理。
        list_append(list, data);
    } else if (index <= 0) {
        //小于等于0，插到最前面
        Node *node = createNewNode(data);
        node->next = list->head;
        list->head = node;
        list->len += 1;
    } else {
        Node *node = createNewNode(data);

        Node *targetParent = getNodeAt(list, index - 1);
        Node *target = targetParent->next;

        if (target == NULL) {
            //这里不应该会这样。因为前面都已经判段过了。
        } else {
            targetParent->next = node;
            node->next = target;
            list->len += 1;
        }
    }


}

Node *getNodeAt(List *list, int index) {
    if (list == NULL) {
        return NULL;
    }

    int len = list->len;
    if (len == 0) {
        return NULL;
    }


    int i = 0;
    Node *target = NULL;
    Node *current = list->head;
    do {

        if (i == index) {
            target = current;
            break;
        } else {
            current = current->next;
            i++;
        }


        if (current == NULL) {
            //到结尾了。
            break;
        } else {
            //可以继续
        }

    } while (i < len);

    return target;

}

void *list_getAt(List *list, int index) {
    Node *target = getNodeAt(list, index);
    if (target == NULL) {
        return NULL;
    } else {
        return target->data;
    }

}

void *list_removeAt(List *list, int index) {
    if (list == NULL) {
        return NULL;
    }

    int len = list->len;
    if (index < 0 || index >= len) {
        assert(0);//index out of boundray
    }

    if (len == 1) {
        Node *node = list->head;
        list->head = NULL;
        list->tail = NULL;
        list->len -= 1;

        void *data = node->data;
        free(node);
        return data;
    }

    if (index == 0) {
        Node *node = list->head;
        list->head = list->head->next;
        list->len -= 1;

        void *data = node->data;
        free(node);
        return data;
    } else {
        Node *targetParent = getNodeAt(list, index - 1);
        Node *target = targetParent->next;

        targetParent->next = target->next;
        list->len -= 1;

        void *data = target->data;
        free(target);
        return data;
    }

}

void list_delete(List **list) {
    if (*list == NULL) {
        return;
    }

    if ((*list)->len > 0) {
        assert(0);//list not empty
    }

    free(*list);
    *list = NULL;
}